<!--
 * @Author: 张鹏
 * @Date: 2025-07-17 20:19:29
 * @LastEditors: fyukeeh 15849141465@163.com
 * @LastEditTime: 2025-07-22 00:07:53
 * @FilePath: \mapbox\src\views\example\TrajectoryPlayback.vue
 * @Description: 
 * 
-->
<template>
    <div class="trajectory-demo">
        <div ref="mapContainer" class="map-container"></div>
        <div class="controls">
            <button @click="play">播放</button>
            <button @click="pause">暂停</button>
            <button @click="stop">停止</button>
            <button @click="showTrajectory">显示轨迹线</button>
            <button @click="hideTrajectory">隐藏轨迹线</button>
            <button @click="toggleProjection">切换3D球/平面</button>
            <label>进度：<input type="range" :max="totalSeconds" v-model.number="progressSeconds" @input="onSeek" /></label>
            <label>速度：<input type="number" v-model.number="speed" min="0.1" step="0.1" @change="onSpeedChange" />x</label>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch, computed } from 'vue';
import Map from '../../../packages';

const mapContainer = ref(null);
let map = null;
let billboards = [];
let trajectoryManagers = [];

// 轨迹点手写两条数据
const entities = [
  {
    name: '实体A',
    points: [
      { lng: 116.391, lat: 39.907, time: '2024-07-18 08:00:00' }, // 北京
      { lng: 114.5025, lat: 38.0455, time: '2024-07-18 08:01:00' }, // 石家庄
      { lng: 113.6254, lat: 34.7466, time: '2024-07-18 08:02:00' }, // 郑州
      { lng: 112.5492, lat: 32.9987, time: '2024-07-18 08:03:00' }  // 襄阳
    ]
  },
  {
    name: '实体B',
    points: [
      { lng: 121.4737, lat: 31.2304, time: '2024-07-18 08:00:00' }, // 上海
      { lng: 120.1551, lat: 30.2741, time: '2024-07-18 08:01:00' }, // 杭州
      { lng: 118.7969, lat: 32.0603, time: '2024-07-18 08:02:00' }, // 南京
      { lng: 117.283, lat: 31.8612, time: '2024-07-18 08:03:00' }, // 合肥
      { lng: 115.8582, lat: 28.6829, time: '2024-07-18 08:04:00' }, // 南昌
      { lng: 113.2806, lat: 23.1252, time: '2024-07-18 08:05:00' }, // 广州
      { lng: 110.3467, lat: 20.0251, time: '2024-07-18 08:06:00' }  // 海口
    ]
  },
  {
    name: '实体C',
    points: [
      { lng: 87.6168, lat: 43.8256, time: '2024-07-18 08:00:00' }, // 乌鲁木齐
      { lng: 103.8343, lat: 36.0611, time: '2024-07-18 08:01:00' }, // 兰州
      { lng: 108.9398, lat: 34.3416, time: '2024-07-18 08:02:00' }, // 西安
      { lng: 106.5505, lat: 29.5638, time: '2024-07-18 08:03:00' }, // 重庆
      { lng: 104.0668, lat: 30.5728, time: '2024-07-18 08:04:00' }, // 成都
      { lng: 102.7123, lat: 25.0406, time: '2024-07-18 08:05:00' }, // 昆明
      { lng: 100.233, lat: 26.8721, time: '2024-07-18 08:06:00' }, // 丽江
      { lng: 98.5795, lat: 24.4337, time: '2024-07-18 08:07:00' }, // 德宏
      { lng: 97.1234, lat: 22.7890, time: '2024-07-18 08:08:00' }, // 瑞丽
      { lng: 95.1234, lat: 21.7890, time: '2024-07-18 08:09:00' }  // 境外
    ]
  }
];

const startTime = new Date(entities[0].points[0].time);
const endTime = new Date(entities[entities.length - 1].points[entities[entities.length - 1].points.length - 1].time);
const totalSeconds = Math.floor((endTime - startTime) / 1000);
const progressSeconds = ref(0);

const currentIndex = ref(0);
const speed = ref(1);
const projectionType = ref('mercator');

function play() {
    trajectoryManagers.forEach(mgr => mgr && mgr.showTrajectory());
    trajectoryManagers.forEach(mgr => mgr && mgr.play());
}
function pause() {
    trajectoryManagers.forEach(mgr => mgr && mgr.pause());
}
function stop() {
    trajectoryManagers.forEach(mgr => mgr && mgr.stop());
    // 强制同步进度条
    progressSeconds.value = 0;
}
function onSeek() {
    if (trajectoryManagers.length > 0) {
        const seekDate = new Date(startTime.getTime() + progressSeconds.value * 1000);
        trajectoryManagers.forEach(mgr => mgr && mgr.setCurrentTime(seekDate));
        // 强制同步进度条
        progressSeconds.value = Math.floor((seekDate - startTime) / 1000);
    }
}
function onSpeedChange() {
    trajectoryManagers.forEach(mgr => mgr && mgr.setSpeed(speed.value));
}

function showTrajectory() {
    trajectoryManagers.forEach(mgr => mgr && mgr.showTrajectory());
}

function hideTrajectory() {
    trajectoryManagers.forEach(mgr => mgr && mgr.hideTrajectory());
}

function toggleProjection() {
    projectionType.value = projectionType.value === 'mercator' ? 'globe' : 'mercator';
    recreateMap();
}

function recreateMap() {
    // 销毁旧地图
    if (map) map.destroy();
    map = new Map(mapContainer.value, {
        scene: {
            center: {
                lng: 116.40,
                lat: 39.90,
                heading: 0,
                pitch: 0
            },
            zoom: 5
        },
        style: 'https://demotiles.maplibre.org/style.json',
        clockStart: startTime,
        clockEnd: endTime,
        clockSpeed: speed.value,
        type: projectionType.value,
        controller: ["showZoom", "showCompass", projectionType.value === 'globe' ? 'globe' : '']
    });
    map.getMapInstance().on('style.load', async () => {
        billboards = [];
        trajectoryManagers = [];
        for (let i = 0; i < entities.length; i++) {
            const entity = entities[i];
            const billboard = new Map.Graphic.BillboardEntity({
                position: [entity.points[0].lng, entity.points[0].lat],
                style: {
                    image: await import('@/assets/images.jpg'),
                    width: 40,
                    height: 40,
                },
            });
            billboards.push(billboard);
            const manager = map.createTrajectoryPlayback(
                billboard,
                entity.points,
                {
                    map: map,
                    lineId: `trajectory_line_${i}_${Date.now()}`,
                    initialLineEmpty: true,
                    onUpdate: idx => {
                        // 只用第一个实体同步进度条
                        if (entity === entities[0] && map && map.getClock) {
                            const curTime = map.getClock().getCurrentTime();
                            progressSeconds.value = Math.floor((curTime - startTime) / 1000);
                        }
                    },
                }
            );
            trajectoryManagers.push(manager);
        }
        // 保证所有manager初始为停止（回到起点）
        trajectoryManagers.forEach(mgr => mgr && mgr.stop());
        progressSeconds.value = 0;
    });
}

onMounted(() => {
    recreateMap();
});

onBeforeUnmount(() => {
    if (map) map.destroy();
});

watch(speed, (val) => {
    trajectoryManagers.forEach(mgr => mgr && mgr.setSpeed(val));
});
</script>

<style scoped>
.trajectory-demo {
    position: relative;
    width: 100%;
    height: 100%;
}

.map-container {
    width: 100%;
    height: 80vh;
    border: 1px solid #ccc;
}

.controls {
    margin-top: 12px;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
    background: rgba(255,255,255,0.85);
    border-radius: 8px;
    padding: 10px 16px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.04);
    width: fit-content;
}
</style>